# -*-* encoding:UTF-8 -*-
# author            : mengy
# date              : 2018/12/10
# python-version    : Python 3.7.0
# description       : 自动抢票

import time
import sys
import urllib
import httplib2
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from splinter.browser import Browser
from com.python.demo.tickets_qry.cities_cookies_code import cities

command = {
    "A": "全部",
    "G": "GC-高铁/城际",
    "D": "D-动车",
    "Z": "Z-直达",
    "Z": "T-特快",
    "K": "K-快速,",
    "O": "O-其他"
}
# 发送短信相关参数
host = "106.ihuyi.com"
sms_send_url = '/webservice/sms.php?method=Submit'
account = 'C89426965'
password = '3f7426082dd5266ae167abe6d998b401'
sms_content = '您的验证码是：156425。请不要把验证码泄露给其他人。'
mobile = '18883985992'

# 发送邮件相关参数
email_host = 'smtp.qq.com'
email_port = 25
email_user = '1215012319@qq.com'
email_pwd = 'vzddgnrijvuhhfff'

# 邮件接收者
receivers = ['mengyanyuan@outlook.com']


class AutoOrderTicket:
    # 指定浏览器
    browser_name = 'chrome'
    # 登录URL
    login_url = 'https://kyfw.12306.cn/otn/resources/login.html'
    # 查询余票URL
    query_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
    # 订票URL
    order_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
    # 12306账户名
    username = 'mengyanyuan@outlook.com'
    # 12306 账户密码
    password = 'dishang0117'
    # 乘车人
    users = [u'周世雄']

    def __init__(self, from_station='重庆', to_station='成都', date='2019-01-01', order=0, limit=sys.maxsize, type='A'):
        self.browser = Browser(self.browser_name)
        # self.browser.driver.set_window_size(1366, 768)
        self.browser.driver.maximize_window()
        self.start = from_station
        self.end = to_station
        self.date = date
        self.limit = limit  # 抢票次数
        self.order = order  # 设置车次
        self.type = type

    def login(self):
        "登录12306"
        self.browser.visit(self.login_url)
        time.sleep(2)
        self.browser.find_by_text('账号登录').click()
        self.browser.find_by_id('J-userName').fill(self.username)
        self.browser.find_by_id('J-password').fill(self.password)
        print(u"等待验证码，自行输入...")
        while True:
            if self.browser.url == 'https://kyfw.12306.cn/otn/view/index.html':
                break
            else:
                time.sleep(1)

    def send_sms(self):
        params = urllib.parse.urlencode({
            'account': account,
            'password': password,
            'content': sms_content,
            'mobile': mobile,
            'format': 'json'
        })
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
        conn = httplib2.HTTPConnectionWithTimeout(host, port=80, timeout=30)
        conn.request("POST", sms_send_url, params, headers)
        response = conn.getresponse()
        result = response.read()
        conn.close()
        print(result)

    def send_email(self):
        message = MIMEText('自动抢票成功，请尽快前往12306完成支付！https://www.12306.cn/index/', 'plain', 'utf-8')
        message['From'] = Header('自动抢票程序', 'utf-8')
        message['To'] = Header('用户', 'utf-8')
        message['Subject'] = Header('订票成功提醒')
        try:
            smtpObj = smtplib.SMTP()
            smtpObj.connect(email_host, email_port)
            smtpObj.login(email_user, email_pwd)
            smtpObj.sendmail(email_user, receivers, message.as_string())
            print('邮件发送成功')
        except Exception as e:
            print('邮件发送失败，失败原因:', e)

    def order_tickets(self):
        self.login()
        self.browser.visit(self.query_url)
        try:
            print(u'开始准备购票...')
            # 加载查询信息
            self.browser.cookies.add({"_jc_save_fromStation": cities[self.start]})
            self.browser.cookies.add({"_jc_save_toStation": cities[self.end]})
            self.browser.cookies.add({"_jc_save_fromDate": self.date})
            self.browser.reload()
            # 循环查询余票
            count = 0
            while self.query_url == self.browser.url and count <= self.limit:
                self.browser.find_by_text(command[self.type]).click()  # 勾选车次类型
                self.browser.find_by_id('query_ticket').click()  # 查询
                count += 1
                print("第 %d 次查询" % count)
                try:
                    if self.order != 0:  # 指定车次的情况
                        self.browser.find_by_text('预订')[self.order - 1].click()
                    else:  # 未指定车次的情况，依次点击各个车次，直到有
                        list = self.browser.find_by_text(u'预订')
                        for item in list:
                            item.click()
                            time.sleep(1)
                            if self.browser.url != self.query_url:
                                break
                except Exception as e:
                    print(e)
                    print(u'暂未预定成功!开始下一次预定')
                    continue

            if count > self.limit:
                print("已经尝试超过 %d 次，查询停止!" % self.limit)
                raise Exception

            print(u'开始预定...')
            time.sleep(1)
            for user in self.users:
                self.browser.find_by_text(user)[1].click()  # 勾选乘车人
            # self.browser.back()
            time.sleep(1)
            print("正在提交订单...")
            # print(self.browser.find_by_text('提交订单'))
            # print(self.browser.driver.find_element_by_xpath("//a[@id='submitOrder_id']"))
            self.browser.driver.find_element_by_xpath("//a[@id='submitOrder_id']").click()
            time.sleep(1)
            print(u'开始选座')
            if self.browser.is_element_present_by_id('1F'):
                self.browser.execute_script("$('#1F').click()")
            print(u'确认选座')
            self.browser.find_by_id('qr_submit_id').click()
            print(u'预定成功，等待支付...')
            # 发送短信通知
            self.send_sms()
            # 发送邮件通知
            self.send_email()
        except Exception as e:
            print(e)

    def __delete__(self, instance):
        self.browser.driver.quit()


if __name__ == '__main__':
    fromStation = input("请输入起始车站:\n")
    toStation = input("请输入目的车站:\n")
    date = input("请输入出行日期:\n")
    type = input("请输入车次类型（A-全部  G-高铁/城际  D-动车  Z-直达  T-特快  K-快速  O-其他）,例如:A \n").upper()  # 忽略大小写
    while type not in command:
        type = input("指令不正确!请重新输入:").upper()
    auto = AutoOrderTicket(fromStation, toStation, date, type=type)
    auto.order_tickets()
